package ifgi.potwc.ipt.sensor;

import ifgi.potwc.ipt.database.IptDatabase;
import ifgi.potwc.ipt.database.IptDatabaseManager;
import ifgi.potwc.ipt.store.Store;
import ifgi.potwc.ipt.ui.SettingsActivity;
import ioio.lib.api.AnalogInput;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOService;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;

/**
 * This class handles measuring sensor data from the IOIO.
 * 
 * @author saschak.
 */
public class IptIOIOService extends IOIOService
{
    // Context for SharedPreferences and Database manager
    private Context ctx;

    // SharedPreferences
    private SharedPreferences prefs;

    // Database manager
    private IptDatabaseManager iptDbm;

    private boolean isFirstTime;

    @Override
    protected IOIOLooper createIOIOLooper()
    {
	return new BaseIOIOLooper()
	{
	    // Analog inputs
	    private AnalogInput inputBri;
	    private AnalogInput inputHum;
	    private AnalogInput inputTmp;

	    @Override
	    protected void setup() throws ConnectionLostException,
		    InterruptedException
	    {
		// Initialize attributes
		ctx = getApplicationContext();
		prefs = SettingsActivity.getPrefs((ContextWrapper) ctx);
		iptDbm = new IptDatabaseManager(ctx);
		isFirstTime = true;

		// IOIO pin numbers
		int briPinNo = Integer.parseInt(prefs.getString(
			"pref_bri_pin_no", "40"));
		int humPinNo = Integer.parseInt(prefs.getString(
			"pref_hum_pin_no", "42"));
		int tmpPinNo = Integer.parseInt(prefs.getString(
			"pref_tmp_pin_no", "44"));

		// Open connections to pins with analog input
		inputBri = ioio_.openAnalogInput(briPinNo);
		inputHum = ioio_.openAnalogInput(humPinNo);
		inputTmp = ioio_.openAnalogInput(tmpPinNo);
	    }

	    @Override
	    public void loop() throws ConnectionLostException,
		    InterruptedException
	    {
		// "Current" feed ID from SharedPreferences
		String feedID = prefs.getString(Store.FEED_ID, "");

		// Read values from the humidity and temperature sensors
		float humValue = inputHum.getVoltage();
		float tmpValue = inputTmp.getVoltage();

		// "Current" timestamp from SharedPreferences
		String timestamp = prefs.getString("timestamp",
			Store.getTimestamp());

		// Save values in the database
		iptDbm.saveValuesInDatabase(feedID, timestamp, humValue,
			IptDatabase.HUM);
		iptDbm.saveValuesInDatabase(feedID, timestamp, tmpValue,
			IptDatabase.TMP);

		// Sensor reading frequencies from SharedPreferences
		int humTmpReadingFreq = Integer.parseInt(prefs.getString(
			"pref_sensors_freq", "15")) * Store.MINUTES;
		int briReadingFreq = Integer.parseInt(prefs.getString(
			"pref_brightness_freq", "5")) * Store.SECONDS;

		if (isFirstTime)
		{
		    isFirstTime = false;

		    Thread.sleep(humTmpReadingFreq);
		}
		else
		{
		    // Ratio between the different sensor reading frequencies
		    int ratio = humTmpReadingFreq / briReadingFreq;

		    // Read the brightness sensor value x times (x = ratio)
		    // before
		    // reading the humidity and temperature sensors again
		    for (int i = 0; i < ratio; i++)
		    {
			// Current timestamp
			String tempTimestamp = Store.getTimestamp();

			// Read the brightness sensor value between 0 = dark and
			// 1 =
			// bright
			float briValue = inputBri.read();

			// Save only if the value is close to 1 (= bright =>
			// parcel
			// has been opened)
			if (briValue > 0.95)
			{
			    // Save value in the database
			    iptDbm.saveValuesInDatabase(feedID, tempTimestamp,
				    briValue, IptDatabase.BRI);
			}

			// Wait x seconds (x = brightness sensor reading
			// frequency)
			Thread.sleep(briReadingFreq);
		    }
		}
	    }
	};
    }

    @Override
    public IBinder onBind(Intent arg0)
    {
	// Binding is not used, so return null
	return null;
    }
}